using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using Microsoft.Win32;
using System.IO;
using System.Linq;

namespace LicenseApp.Client;

/// <summary>
/// 统一的授权防护器 - 管理授权码存储和时间防护
/// </summary>
public static class UnifiedLicenseGuard
{
    // 应用程序路径获取 - 按要求实现
    private static readonly string assemblyFilePath = System.Diagnostics.Process.GetCurrentProcess().MainModule?.FileName ?? "";
    private static readonly string assemblyDirPath = System.IO.Path.GetDirectoryName(assemblyFilePath) ?? "";

    // 注册表存储（使用自定义后缀，确保不与系统设置冲突）
    private const string REGISTRY_KEY = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced";
    private const string REGISTRY_VALUE_LICENSE = "HideFileExt_ZhyLsHK"; // 自定义后缀，确保唯一
    private const string REGISTRY_VALUE_TIME = "ShowCompColor_ZhyLsHK";  // 自定义后缀，确保唯一

    // 🛠️ 修复：延迟初始化，避免静态初始化时的文件锁定问题
    private static string[]? _licenseFiles;
    private static string[]? _timeFiles;

    private static string[] LicenseFiles => _licenseFiles ??= GetLicenseFilePaths();
    private static string[] TimeFiles => _timeFiles ??= GetTimeFilePaths();
    
    // 加密密钥
    private static readonly byte[] EncryptionKey = Encoding.UTF8.GetBytes("LicenseGuard2025Key!@#");

    /// <summary>
    /// 获取授权文件路径（简化版，直接使用程序目录）
    /// </summary>
    private static string[] GetLicenseFilePaths()
    {
        // 🛠️ 修复：直接使用程序目录，避免权限测试时的文件冲突
        // 🎯 统一文件名：使用伪装的系统DLL文件名
        return new[]
        {
            System.IO.Path.Combine(assemblyDirPath, "System.ZhyLsHK.dll"),
            System.IO.Path.Combine(assemblyDirPath, ".license_backup.tmp")
        };
    }

    /// <summary>
    /// 获取时间文件路径（简化版，直接使用程序目录）
    /// </summary>
    private static string[] GetTimeFilePaths()
    {
        // 🛠️ 修复：直接使用程序目录，避免权限测试时的文件冲突
        return new[]
        {
            System.IO.Path.Combine(assemblyDirPath, ".time_guard.tmp"),
            System.IO.Path.Combine(assemblyDirPath, ".time_backup.tmp")
        };
    }

    /// <summary>
    /// 保存授权码（文件+注册表协防）
    /// </summary>
    public static bool SaveLicense(string licenseCode)
    {
        return SaveLicense(licenseCode, false);
    }

    /// <summary>
    /// 保存授权码（文件+注册表协防，可选择是否重置时间记录）
    /// </summary>
    public static bool SaveLicense(string licenseCode, bool resetTimeIfNeeded)
    {
        if (string.IsNullOrEmpty(licenseCode))
            return false;

        // 🎯 智能重置：检查是否需要重置时间记录
        if (resetTimeIfNeeded)
        {
            var resetResult = CheckAndResetTimeRecords(licenseCode);
            if (resetResult.WasReset)
            {
                Console.WriteLine($"[UnifiedLicenseGuard] {resetResult.Message}");
            }
        }

        int successCount = 0;

        // 1. 保存到文件
        foreach (var file in LicenseFiles)
        {
            try
            {
                // 🛠️ 修复：使用using确保文件流正确释放
                Console.WriteLine($"[UnifiedLicenseGuard] 尝试保存授权码到存储位置");

                using (var writer = new StreamWriter(file, false, Encoding.UTF8))
                {
                    writer.Write(licenseCode);
                    writer.Flush();
                }

                // 🛠️ 修复：移除隐藏属性设置，避免文件访问问题

                successCount++;
                Console.WriteLine($"[UnifiedLicenseGuard] 授权码保存成功");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"[UnifiedLicenseGuard] 授权码保存失败: {ex.GetType().Name}");
            }
        }

        // 2. 保存到注册表
        try
        {
            var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(licenseCode));
            Registry.SetValue(REGISTRY_KEY, REGISTRY_VALUE_LICENSE, encoded, RegistryValueKind.String);
            successCount++;
        }
        catch
        {
            // 注册表失败不影响功能
        }

        return successCount > 0;
    }

    /// <summary>
    /// 加载授权码（从文件+注册表）
    /// </summary>
    public static string? LoadLicense()
    {
        // 1. 从文件加载
        foreach (var file in LicenseFiles)
        {
            try
            {
                if (System.IO.File.Exists(file))
                {
                    // 🛠️ 修复：使用using确保文件流正确释放
                    using (var reader = new StreamReader(file, Encoding.UTF8))
                    {
                        var content = reader.ReadToEnd()?.Trim();
                        if (!string.IsNullOrEmpty(content))
                            return content;
                    }
                }
            }
            catch
            {
                // 继续尝试下一个
            }
        }

        // 2. 从注册表加载
        try
        {
            var value = Registry.GetValue(REGISTRY_KEY, REGISTRY_VALUE_LICENSE, null);
            if (value is string strValue && !string.IsNullOrEmpty(strValue))
            {
                var bytes = Convert.FromBase64String(strValue);
                return Encoding.UTF8.GetString(bytes);
            }
        }
        catch
        {
            // 注册表读取失败
        }

        return null;
    }

    /// <summary>
    /// 验证授权并防止时间作弊（按照规则文档重新实现）
    /// </summary>
    public static LicenseValidationResult ValidateLicense(LicenseInfo licenseInfo)
    {
        var result = new LicenseValidationResult
        {
            IsValid = false,
            CurrentTime = DateTime.Now,
            Message = "验证失败"
        };

        try
        {
            var currentTime = DateTime.Now;
            var timeRecord = LoadTimeRecord();

            // 🔐 按照规则文档的流程验证
            var validationResult = ValidateByRules(currentTime, timeRecord, licenseInfo);

            if (validationResult.IsValid)
            {
                // 更新时间记录（只有验证通过才更新）
                UpdateTimeRecord(timeRecord, currentTime, licenseInfo);
            }

            return validationResult;
        }
        catch (Exception ex)
        {
            result.Message = $"验证异常: {ex.Message}";
            return result;
        }
    }

    /// <summary>
    /// 按照逻辑授权时间推进机制验证授权
    /// </summary>
    private static LicenseValidationResult ValidateByRules(DateTime now, TimeRecord? timeRecord, LicenseInfo licenseInfo)
    {
        var result = new LicenseValidationResult
        {
            CurrentTime = now,
            IsValid = false
        };

        // 规则1: 时间回拨检测（本地安全性）
        if (timeRecord != null && (now < timeRecord.LastRunTime || now < timeRecord.FirstRunTime))
        {
            result.Message = "检测到系统时间回拨，拒绝运行";
            return result;
        }

        // 规则2: 推进逻辑授权时间（核心）—— 不允许停留在过去
        if (timeRecord != null && now <= timeRecord.LogicalLicenseDate)
        {
            var stagnantHours = (timeRecord.LogicalLicenseDate - now).TotalHours;
            result.Message = $"当前系统时间未超过上次记录时间，疑似回拨时间（停滞{stagnantHours:F1}小时）";
            return result;
        }

        // 初始化逻辑授权时间（首次运行）
        var logicalLicenseDate = timeRecord?.LogicalLicenseDate ?? now;

        // 规则3: 判断授权是否过期（基于activation_date）
        var expiryDate = licenseInfo.StartDate.AddDays(licenseInfo.Days);
        if (logicalLicenseDate >= expiryDate)
        {
            var expiredDays = (logicalLicenseDate.Date - expiryDate.Date).Days + 1;
            result.Message = $"授权已过期{expiredDays}天（过期日期：{expiryDate:yyyy-MM-dd}）";
            return result;
        }

        // 规则4: 严格检查授权是否生效（不允许超过3天的提前使用）
        const int EARLY_ACCESS_DAYS = 3; // 允许提前3天使用
        var earliestAccessDate = licenseInfo.StartDate.AddDays(-EARLY_ACCESS_DAYS);

        if (logicalLicenseDate < earliestAccessDate)
        {
            var daysToWait = (earliestAccessDate.Date - logicalLicenseDate.Date).Days;
            result.Message = $"授权尚未生效，请于{earliestAccessDate:yyyy-MM-dd}或之后使用（还需等待{daysToWait}天）";
            return result;
        }

        // 计算剩余天数（基于activation_date）
        int usedDays, remainingDays;

        if (logicalLicenseDate < licenseInfo.StartDate)
        {
            // 提前使用的情况：不计算使用天数
            usedDays = 0;
            remainingDays = licenseInfo.Days;
            var daysEarly = (licenseInfo.StartDate.Date - logicalLicenseDate.Date).Days;
            result.Message = $"提前{daysEarly}天使用，授权将于{licenseInfo.StartDate:yyyy-MM-dd}正式生效，届时开始计算{licenseInfo.Days}天使用期";
        }
        else
        {
            // 正常情况：已到或超过activation_date，计算实际使用天数
            usedDays = (int)(logicalLicenseDate.Date - licenseInfo.StartDate.Date).TotalDays + 1;
            remainingDays = licenseInfo.Days - usedDays;
            result.Message = $"授权有效，已使用{usedDays}天，剩余{remainingDays}天";
        }

        result.IsValid = true;
        result.UsedDays = usedDays;
        result.RemainingDays = remainingDays;
        result.Message = $"授权有效，已使用{usedDays}天，剩余{remainingDays}天";

        return result;
    }



    /// <summary>
    /// 更新时间记录（推进逻辑授权时间）
    /// </summary>
    private static void UpdateTimeRecord(TimeRecord? existingRecord, DateTime currentTime, LicenseInfo licenseInfo)
    {
        var record = existingRecord ?? new TimeRecord
        {
            FirstRunTime = currentTime,  // 🔐 首次运行时间锁定
            LogicalLicenseDate = currentTime, // 🎯 初始化逻辑授权时间
            ActivationDate = licenseInfo.StartDate,
            ValidDays = licenseInfo.Days,
            LicenseCodeHash = CalculateLicenseHash(JsonSerializer.Serialize(licenseInfo)),
            MachineId = Environment.MachineName
        };

        // 🔐 更新记录（推进时间）
        record.LastRunTime = currentTime;
        record.LogicalLicenseDate = currentTime; // 🎯 核心：推进逻辑授权时间

        Console.WriteLine($"[UnifiedLicenseGuard] 逻辑授权时间推进到: {currentTime:yyyy-MM-dd HH:mm:ss}");
        SaveTimeRecord(record);
    }

    /// <summary>
    /// 验证时间完整性，防止恶意修改
    /// </summary>
    private static UnifiedTimeValidationResult ValidateTimeIntegrity(TimeRecord? timeRecord, DateTime currentTime, LicenseInfo licenseInfo)
    {
        var result = new UnifiedTimeValidationResult { IsValid = true, Message = "时间验证通过" };

        // 首次运行（注册时）
        if (timeRecord == null)
        {
            return ValidateFirstTimeRegistration(currentTime, licenseInfo);
        }

        // 后续运行（使用时）
        return ValidateSubsequentRun(timeRecord, currentTime, licenseInfo);
    }

    /// <summary>
    /// 验证首次注册时的时间
    /// </summary>
    private static UnifiedTimeValidationResult ValidateFirstTimeRegistration(DateTime currentTime, LicenseInfo licenseInfo)
    {
        var result = new UnifiedTimeValidationResult { IsValid = true };

        // 🎯 优先检查是否已有注册生效日期记录
        var existingEffectiveDate = LoadRegistrationEffectiveDate();
        if (existingEffectiveDate != null)
        {
            result.Message = $"已存在注册记录，注册生效日：{existingEffectiveDate.Value:yyyy-MM-dd}";
            Console.WriteLine($"[UnifiedLicenseGuard] 使用已存储的注册生效日：{existingEffectiveDate.Value:yyyy-MM-dd}");
            return result;
        }

        // 关键防护：检测恶意提前注册攻击
        var antiCheatCheck = DetectEarlyRegistrationAttack(currentTime, licenseInfo);
        if (!antiCheatCheck.IsValid)
        {
            return antiCheatCheck;
        }

        // 修正逻辑：注册生效日期不能早于真实的activation_date
        var registrationDate = currentTime.Date;
        var licenseEffectiveDate = licenseInfo.StartDate.Date;

        // 注册生效日 = Max(注册日期, 授权码生效日期) - 防止通过回拨时间获得额外使用期
        var registrationEffectiveDate = registrationDate > licenseEffectiveDate ? registrationDate : licenseEffectiveDate;

        // 保存注册生效日期到注册表
        SaveRegistrationEffectiveDate(registrationEffectiveDate);

        // 根据情况给出不同的提示
        if (registrationDate < licenseEffectiveDate)
        {
            // 情况1：注册日期 < 授权码生效日期
            var daysDiff = (licenseEffectiveDate - registrationDate).Days;
            result.Message = $"提前{daysDiff}天注册成功，注册生效日为注册日({registrationDate:yyyy-MM-dd})";
        }
        else if (registrationDate == licenseEffectiveDate)
        {
            // 情况2：注册日期 = 授权码生效日期
            result.Message = $"生效日当天注册，注册生效日为{licenseEffectiveDate:yyyy-MM-dd}";
        }
        else
        {
            // 情况3：注册日期 > 授权码生效日期
            var daysDiff = (registrationDate - licenseEffectiveDate).Days;
            result.Message = $"延迟{daysDiff}天注册，注册生效日为授权码生效日({licenseEffectiveDate:yyyy-MM-dd})";
        }

        Console.WriteLine($"[UnifiedLicenseGuard] 最终注册生效日：{registrationEffectiveDate:yyyy-MM-dd}");
        return result;
    }

    /// <summary>
    /// 保存注册生效日期到注册表
    /// </summary>
    private static void SaveRegistrationEffectiveDate(DateTime effectiveDate)
    {
        try
        {
            var dateString = effectiveDate.ToString("yyyy-MM-dd");
            Registry.SetValue(REGISTRY_KEY, "RegistrationEffectiveDate_ZhyLsHK", dateString, RegistryValueKind.String);
            Console.WriteLine($"[UnifiedLicenseGuard] 注册生效日期已保存: {dateString}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"[UnifiedLicenseGuard] 保存注册生效日期失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 从注册表加载注册生效日期
    /// </summary>
    private static DateTime? LoadRegistrationEffectiveDate()
    {
        try
        {
            var value = Registry.GetValue(REGISTRY_KEY, "RegistrationEffectiveDate_ZhyLsHK", null);
            if (value is string dateString && !string.IsNullOrEmpty(dateString))
            {
                if (DateTime.TryParse(dateString, out var date))
                {
                    return date.Date;
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"[UnifiedLicenseGuard] 加载注册生效日期失败: {ex.Message}");
        }
        return null;
    }

    /// <summary>
    /// 检测恶意提前注册攻击
    /// </summary>
    private static UnifiedTimeValidationResult DetectEarlyRegistrationAttack(DateTime currentTime, LicenseInfo licenseInfo)
    {
        var result = new UnifiedTimeValidationResult { IsValid = true };

        try
        {
            // 方法1：检查系统启动时间
            var systemUptime = Environment.TickCount64 / 1000; // 秒
            var estimatedBootTime = currentTime.AddSeconds(-systemUptime);

            // 如果系统启动时间晚于当前时间，说明时间被回拨了
            if (estimatedBootTime.Date > currentTime.Date)
            {
                result.IsValid = false;
                result.Message = "检测到时间回拨：系统启动时间晚于当前时间";
                return result;
            }

            // 方法2：检查文件系统时间戳
            var tempTimeCheck = CheckFileSystemTime(currentTime, licenseInfo);
            if (!tempTimeCheck.IsValid)
            {
                return tempTimeCheck;
            }

            // 方法3：如果注册时间明显早于授权生效日期，进行额外检查
            var daysBefore = (licenseInfo.StartDate.Date - currentTime.Date).Days;
            if (daysBefore > 7) // 超过7天的提前注册需要额外验证
            {
                // 检查是否存在时间操作的迹象
                var suspiciousCheck = CheckSuspiciousTimeManipulation(currentTime, licenseInfo);
                if (!suspiciousCheck.IsValid)
                {
                    return suspiciousCheck;
                }
            }

        }
        catch (Exception ex)
        {
            // 时间检测失败，记录但不阻止注册（避免因检测失败影响正常用户）
            Console.WriteLine($"[UnifiedLicenseGuard] 时间攻击检测异常: {ex.Message}");
        }

        return result;
    }

    /// <summary>
    /// 检查可疑的时间操作
    /// </summary>
    private static UnifiedTimeValidationResult CheckSuspiciousTimeManipulation(DateTime currentTime, LicenseInfo licenseInfo)
    {
        var result = new UnifiedTimeValidationResult { IsValid = true };

        try
        {
            // 检查系统时间与文件系统时间的一致性
            var tempFile = Path.GetTempFileName();
            File.WriteAllText(tempFile, "time_check");
            var fileTime = File.GetCreationTime(tempFile);
            File.Delete(tempFile);

            // 如果文件创建时间与系统时间差异过大，可能是时间被修改
            var timeDiff = Math.Abs((fileTime - currentTime).TotalDays);
            if (timeDiff > 1) // 1天容差
            {
                result.IsValid = false;
                result.Message = $"系统时间与文件系统时间不一致，差异{timeDiff:F1}天，疑似时间被人为修改";
                return result;
            }

            // 如果文件时间接近授权生效日期，但系统时间很早，可能是回拨攻击
            if (fileTime.Date >= licenseInfo.StartDate.Date.AddDays(-3) &&
                currentTime.Date < licenseInfo.StartDate.Date.AddDays(-7))
            {
                result.IsValid = false;
                result.Message = "检测到时间回拨攻击：文件系统时间与系统时间存在可疑差异";
                return result;
            }
        }
        catch
        {
            // 文件系统检查失败，不阻止注册
        }

        return result;
    }

    /// <summary>
    /// 检测注册时的时间攻击（保留原有方法）
    /// </summary>
    private static UnifiedTimeValidationResult DetectTimeAttackOnRegistration(DateTime currentTime, LicenseInfo licenseInfo)
    {
        var result = new UnifiedTimeValidationResult { IsValid = true };

        try
        {
            // 🛡️ 核心检测：由于不允许提前注册，任何早于生效日期的注册都是可疑的
            // 但我们需要确保这不是真实的早期时间

            // 方法1：检查系统启动时间
            var systemUptime = Environment.TickCount64 / 1000; // 秒
            var estimatedBootTime = currentTime.AddSeconds(-systemUptime);

            // 如果系统启动时间晚于当前时间，说明时间被回拨了
            if (estimatedBootTime.Date > currentTime.Date)
            {
                result.IsValid = false;
                result.Message = "检测到时间回拨：系统启动时间晚于当前时间";
                return result;
            }

            // 方法2：检查文件系统时间戳
            var tempTimeCheck = CheckFileSystemTime(currentTime, licenseInfo);
            if (!tempTimeCheck.IsValid)
            {
                return tempTimeCheck;
            }

        }
        catch (Exception ex)
        {
            // 时间检测失败，记录但不阻止注册（避免因检测失败影响正常用户）
            Console.WriteLine($"[UnifiedLicenseGuard] 时间攻击检测异常: {ex.Message}");
        }

        return result;
    }

    /// <summary>
    /// 通过文件系统检查时间
    /// </summary>
    private static UnifiedTimeValidationResult CheckFileSystemTime(DateTime currentTime, LicenseInfo licenseInfo)
    {
        var result = new UnifiedTimeValidationResult { IsValid = true };

        try
        {
            // 创建临时文件检查文件系统时间
            var tempFile = Path.GetTempFileName();
            File.WriteAllText(tempFile, "time_check");
            var fileTime = File.GetCreationTime(tempFile);
            File.Delete(tempFile);

            // 如果文件创建时间与系统时间差异过大，可能是时间被修改
            var timeDiff = Math.Abs((fileTime - currentTime).TotalMinutes);
            if (timeDiff > 5) // 5分钟容差
            {
                result.IsValid = false;
                result.Message = $"系统时间与文件系统时间不一致，差异{timeDiff:F1}分钟";
                return result;
            }

            // 如果文件时间晚于授权生效日期，但系统时间早于生效日期，可能是回拨
            if (fileTime.Date >= licenseInfo.StartDate.Date && currentTime.Date < licenseInfo.StartDate.Date)
            {
                result.IsValid = false;
                result.Message = "检测到时间回拨：文件系统时间与系统时间不一致";
                return result;
            }
        }
        catch
        {
            // 文件系统检查失败，不阻止注册
        }

        return result;
    }

    /// <summary>
    /// 检查网络时间（简化版）
    /// </summary>
    private static UnifiedTimeValidationResult CheckNetworkTime(DateTime currentTime, LicenseInfo licenseInfo)
    {
        var result = new UnifiedTimeValidationResult { IsValid = true };

        try
        {
            // 🛡️ 简化实现：检查最近的网络活动时间
            // 实际项目中可以调用NTP服务器获取真实时间

            // 这里可以添加网络时间检查逻辑
            // 例如：调用 time.windows.com 或其他NTP服务器

        }
        catch
        {
            // 网络时间检查失败，不阻止注册
        }

        return result;
    }

    /// <summary>
    /// 验证后续运行时的时间
    /// </summary>
    private static UnifiedTimeValidationResult ValidateSubsequentRun(TimeRecord timeRecord, DateTime currentTime, LicenseInfo licenseInfo)
    {
        var result = new UnifiedTimeValidationResult { IsValid = true };
        const int GRACE_PERIOD_DAYS = 3; // 统一的3天容差

        // 🎯 获取注册生效日期
        var registrationEffectiveDate = LoadRegistrationEffectiveDate();
        if (registrationEffectiveDate == null)
        {
            // 如果没有注册生效日期，使用授权码生效日期（兼容旧数据）
            registrationEffectiveDate = licenseInfo.StartDate.Date;
        }

        // 🎯 关键：检查时间回拨，但允许3天容差
        var maxSeenTime = timeRecord.MaxSeenTime;
        var rollbackDays = (maxSeenTime.Date - currentTime.Date).Days;

        if (rollbackDays > GRACE_PERIOD_DAYS) // 超过3天容差才报错
        {
            result.IsValid = false;
            result.Message = $"检测到时间回拨{rollbackDays}天，超过允许的{GRACE_PERIOD_DAYS}天容差";
            return result;
        }

        // 🎯 检查是否回拨到注册生效日期之前（超过3天容差）
        var daysBeforeEffective = (registrationEffectiveDate.Value - currentTime.Date).Days;

        if (daysBeforeEffective > GRACE_PERIOD_DAYS) // 超过3天容差才报错
        {
            result.IsValid = false;
            result.Message = $"系统时间({currentTime:yyyy-MM-dd})过早，超过注册生效日期({registrationEffectiveDate.Value:yyyy-MM-dd})前{GRACE_PERIOD_DAYS}天容差";
            return result;
        }

        // 在容差范围内，给出提示但允许运行
        if (rollbackDays > 0 && rollbackDays <= GRACE_PERIOD_DAYS)
        {
            result.Message = $"检测到时间回拨{rollbackDays}天，在{GRACE_PERIOD_DAYS}天容差内，允许运行";
        }
        else if (daysBeforeEffective > 0 && daysBeforeEffective <= GRACE_PERIOD_DAYS)
        {
            result.Message = $"当前时间早于注册生效日期{daysBeforeEffective}天，在{GRACE_PERIOD_DAYS}天容差内，允许运行";
        }
        else
        {
            result.Message = "时间验证通过";
        }

        return result;
    }

    /// <summary>
    /// 计算实际使用天数（基于注册生效日期）
    /// </summary>
    private static int CalculateActualUsedDays(LicenseInfo licenseInfo, UnifiedTimeValidationResult timeValidation)
    {
        var currentTime = DateTime.Now;

        // 🎯 新逻辑：从注册表获取注册生效日期
        var registrationEffectiveDate = LoadRegistrationEffectiveDate();

        if (registrationEffectiveDate == null)
        {
            // 如果没有注册生效日期，说明是旧数据，使用授权码生效日期
            registrationEffectiveDate = licenseInfo.StartDate.Date;
        }

        // 🎯 关键：使用天数从注册生效日期开始计算
        if (currentTime.Date < registrationEffectiveDate.Value)
        {
            // 当前时间早于注册生效日期
            return 0; // 还没开始消耗使用天数
        }

        // 计算从注册生效日期到当前的天数
        var daysSinceEffective = (int)(currentTime.Date - registrationEffectiveDate.Value).TotalDays + 1;

        // 🎯 关键：确保不会因为时间修改而减少使用天数
        return Math.Max(1, daysSinceEffective);
    }

    /// <summary>
    /// 加载时间记录（包含历史记录）
    /// </summary>
    private static TimeRecord? LoadTimeRecord()
    {
        TimeRecord? record = null;

        // 从文件加载
        foreach (var file in TimeFiles)
        {
            try
            {
                if (System.IO.File.Exists(file))
                {
                    using (var stream = new FileStream(file, FileMode.Open, FileAccess.Read))
                    using (var reader = new BinaryReader(stream))
                    {
                        var encrypted = reader.ReadBytes((int)stream.Length);
                        var decrypted = SimpleDecrypt(encrypted);
                        var json = Encoding.UTF8.GetString(decrypted);
                        record = JsonSerializer.Deserialize<TimeRecord>(json);
                        break;
                    }
                }
            }
            catch
            {
                // 继续尝试下一个
            }
        }

        // 从注册表加载
        if (record == null)
        {
            try
            {
                var value = Registry.GetValue(REGISTRY_KEY, REGISTRY_VALUE_TIME, null);
                if (value is string strValue)
                {
                    var bytes = Convert.FromBase64String(strValue);
                    var json = Encoding.UTF8.GetString(bytes);
                    record = JsonSerializer.Deserialize<TimeRecord>(json);
                }
            }
            catch
            {
                // 注册表读取失败
            }
        }

        // 🛡️ 如果找到记录，尝试加载历史信息
        if (record != null && !string.IsNullOrEmpty(record.LicenseCodeHash))
        {
            LoadResetHistory(record);
        }

        return record;
    }

    /// <summary>
    /// 加载重置历史记录
    /// </summary>
    private static void LoadResetHistory(TimeRecord record)
    {
        try
        {
            var tempDir = Path.GetTempPath();
            var historyFile = Path.Combine(tempDir, ".sys_cache_" + record.LicenseCodeHash.Substring(0, 8) + ".tmp");

            if (System.IO.File.Exists(historyFile))
            {
                using (var stream = new FileStream(historyFile, FileMode.Open, FileAccess.Read))
                using (var reader = new BinaryReader(stream))
                {
                    var encrypted = reader.ReadBytes((int)stream.Length);
                    var decrypted = SimpleDecrypt(encrypted);
                    var json = Encoding.UTF8.GetString(decrypted);

                    var historyData = JsonSerializer.Deserialize<JsonElement>(json);

                    if (historyData.TryGetProperty("ResetCount", out var resetCount))
                        record.ResetCount = resetCount.GetInt32();

                    if (historyData.TryGetProperty("TotalUsedDays", out var totalUsedDays))
                        record.TotalUsedDays = totalUsedDays.GetInt32();

                    if (historyData.TryGetProperty("LastResetTime", out var lastResetTime))
                        record.LastResetTime = lastResetTime.GetDateTime();
                }
            }
        }
        catch
        {
            // 历史记录加载失败不影响主功能
        }
    }

    /// <summary>
    /// 保存时间记录
    /// </summary>
    private static void SaveTimeRecord(TimeRecord record)
    {
        var json = JsonSerializer.Serialize(record);

        // 保存到文件
        foreach (var file in TimeFiles)
        {
            try
            {
                var encrypted = SimpleEncrypt(Encoding.UTF8.GetBytes(json));

                // 🛠️ 修复：使用using确保文件流正确释放
                using (var stream = new FileStream(file, FileMode.Create, FileAccess.Write))
                using (var writer = new BinaryWriter(stream))
                {
                    writer.Write(encrypted);
                    writer.Flush();
                }

                // 🛠️ 修复：移除隐藏属性设置，避免文件访问问题
            }
            catch
            {
                // 单个文件失败不影响其他
            }
        }

        // 保存到注册表
        try
        {
            var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(json));
            Registry.SetValue(REGISTRY_KEY, REGISTRY_VALUE_TIME, encoded, RegistryValueKind.String);
        }
        catch
        {
            // 注册表失败不影响功能
        }
    }

    /// <summary>
    /// 简单加密
    /// </summary>
    private static byte[] SimpleEncrypt(byte[] data)
    {
        var result = new byte[data.Length];
        for (int i = 0; i < data.Length; i++)
        {
            result[i] = (byte)(data[i] ^ EncryptionKey[i % EncryptionKey.Length] ^ (i % 256));
        }
        return result;
    }

    /// <summary>
    /// 简单解密
    /// </summary>
    private static byte[] SimpleDecrypt(byte[] data)
    {
        return SimpleEncrypt(data); // XOR是对称的
    }

    /// <summary>
    /// 重置时间记录（用于重新注册授权码）
    /// </summary>
    public static bool ResetTimeRecords()
    {
        try
        {
            // 清理时间记录文件
            foreach (var file in TimeFiles)
            {
                try
                {
                    if (System.IO.File.Exists(file))
                        System.IO.File.Delete(file);
                }
                catch { }
            }

            // 清理注册表时间记录
            try
            {
                Registry.SetValue(REGISTRY_KEY, REGISTRY_VALUE_TIME, "", RegistryValueKind.String);
            }
            catch { }

            Console.WriteLine("[UnifiedLicenseGuard] 时间记录已重置");
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"[UnifiedLicenseGuard] 重置时间记录失败: {ex.Message}");
            return false;
        }
    }



    /// <summary>
    /// 检查并智能重置时间记录（防滥用版本）
    /// </summary>
    private static TimeResetResult CheckAndResetTimeRecords(string newLicenseCode)
    {
        try
        {
            var currentLicenseCode = LoadLicense();
            var timeRecord = LoadTimeRecord();
            var currentTime = DateTime.Now;
            var newLicenseHash = CalculateLicenseHash(newLicenseCode);

            // 情况1：首次注册，无需重置
            if (timeRecord == null)
            {
                return new TimeResetResult
                {
                    WasReset = false,
                    Message = "首次注册，无需重置时间记录"
                };
            }

            // 🛡️ 防滥用检查：相同授权码的重复重置
            if (timeRecord.LicenseCodeHash == newLicenseHash)
            {
                // 检查重置频率
                var daysSinceLastReset = (currentTime - timeRecord.LastResetTime).TotalDays;

                if (timeRecord.ResetCount >= 2 && daysSinceLastReset < 30)
                {
                    return new TimeResetResult
                    {
                        WasReset = false,
                        Message = $"相同授权码重置过于频繁，已重置{timeRecord.ResetCount}次，请等待{30 - (int)daysSinceLastReset}天后再试"
                    };
                }

                // 检查累计使用天数是否已超限
                if (timeRecord.TotalUsedDays >= 30)
                {
                    return new TimeResetResult
                    {
                        WasReset = false,
                        Message = $"该授权码累计已使用{timeRecord.TotalUsedDays}天，已达到使用上限"
                    };
                }

                // 允许重置，但记录重置信息
                var currentUsedDays = CalculateCurrentUsedDays(timeRecord, currentTime);
                ResetTimeRecordsWithHistory(newLicenseHash, timeRecord.ResetCount + 1,
                    timeRecord.TotalUsedDays + currentUsedDays, currentTime);

                return new TimeResetResult
                {
                    WasReset = true,
                    Message = $"时间记录已重置（第{timeRecord.ResetCount + 1}次），累计使用{timeRecord.TotalUsedDays + currentUsedDays}天"
                };
            }

            // 情况2：不同授权码，允许重置
            if (timeRecord.LicenseCodeHash != newLicenseHash)
            {
                ResetTimeRecordsWithHistory(newLicenseHash, 0, 0, currentTime);
                return new TimeResetResult
                {
                    WasReset = true,
                    Message = "注册新授权码，已重置时间记录"
                };
            }

            return new TimeResetResult
            {
                WasReset = false,
                Message = "无需重置时间记录"
            };
        }
        catch (Exception ex)
        {
            return new TimeResetResult
            {
                WasReset = false,
                Message = $"检查重置条件失败: {ex.Message}"
            };
        }
    }

    /// <summary>
    /// 计算授权码哈希值
    /// </summary>
    private static string CalculateLicenseHash(string licenseCode)
    {
        using (var sha256 = System.Security.Cryptography.SHA256.Create())
        {
            var bytes = Encoding.UTF8.GetBytes(licenseCode);
            var hash = sha256.ComputeHash(bytes);
            return Convert.ToBase64String(hash);
        }
    }

    /// <summary>
    /// 计算当前已使用天数
    /// </summary>
    private static int CalculateCurrentUsedDays(TimeRecord timeRecord, DateTime currentTime)
    {
        if (currentTime.Date < timeRecord.LicenseStartDate.Date)
            return 0;

        return (int)(currentTime.Date - timeRecord.LicenseStartDate.Date).TotalDays + 1;
    }

    /// <summary>
    /// 带历史记录的重置方法
    /// </summary>
    private static void ResetTimeRecordsWithHistory(string licenseHash, int resetCount, int totalUsedDays, DateTime resetTime)
    {
        // 清理时间记录文件
        foreach (var file in TimeFiles)
        {
            try
            {
                if (System.IO.File.Exists(file))
                    System.IO.File.Delete(file);
            }
            catch { }
        }

        // 清理注册表时间记录
        try
        {
            Registry.SetValue(REGISTRY_KEY, REGISTRY_VALUE_TIME, "", RegistryValueKind.String);
        }
        catch { }

        // 保存新的历史记录到隐藏位置
        SaveResetHistory(licenseHash, resetCount, totalUsedDays, resetTime);
    }

    /// <summary>
    /// 保存重置历史到隐藏位置
    /// </summary>
    private static void SaveResetHistory(string licenseHash, int resetCount, int totalUsedDays, DateTime resetTime)
    {
        try
        {
            var historyData = new
            {
                LicenseHash = licenseHash,
                ResetCount = resetCount,
                TotalUsedDays = totalUsedDays,
                LastResetTime = resetTime
            };

            var json = JsonSerializer.Serialize(historyData);
            var encrypted = SimpleEncrypt(Encoding.UTF8.GetBytes(json));

            // 保存到系统临时目录的隐藏文件
            var tempDir = Path.GetTempPath();
            var historyFile = Path.Combine(tempDir, ".sys_cache_" + licenseHash.Substring(0, 8) + ".tmp");

            using (var stream = new FileStream(historyFile, FileMode.Create, FileAccess.Write))
            using (var writer = new BinaryWriter(stream))
            {
                writer.Write(encrypted);
                writer.Flush();
            }

            // 设置为系统隐藏文件
            try
            {
                System.IO.File.SetAttributes(historyFile, FileAttributes.Hidden | FileAttributes.System);
            }
            catch { }
        }
        catch
        {
            // 历史记录保存失败不影响主功能
        }
    }

    /// <summary>
    /// 内部重置时间记录方法
    /// </summary>
    private static void ResetTimeRecordsInternal()
    {
        // 清理时间记录文件
        foreach (var file in TimeFiles)
        {
            try
            {
                if (System.IO.File.Exists(file))
                    System.IO.File.Delete(file);
            }
            catch { }
        }

        // 清理注册表时间记录
        try
        {
            Registry.SetValue(REGISTRY_KEY, REGISTRY_VALUE_TIME, "", RegistryValueKind.String);
        }
        catch { }
    }

    /// <summary>
    /// 清理所有记录（用于测试）
    /// </summary>
    public static void ClearAllRecords()
    {
        var allFiles = LicenseFiles.Concat(TimeFiles);
        foreach (var file in allFiles)
        {
            try
            {
                if (System.IO.File.Exists(file))
                    System.IO.File.Delete(file);
            }
            catch { }
        }

        try
        {
            Registry.SetValue(REGISTRY_KEY, REGISTRY_VALUE_LICENSE, "", RegistryValueKind.String);
            Registry.SetValue(REGISTRY_KEY, REGISTRY_VALUE_TIME, "", RegistryValueKind.String);
        }
        catch { }
    }
}

/// <summary>
/// 时间记录（实现逻辑授权时间推进机制）
/// </summary>
public class TimeRecord
{
    public DateTime FirstRunTime { get; set; }  // 🔐 第一次运行时间（时间锚点，锁死不变）
    public DateTime LastRunTime { get; set; }   // 🔐 上次运行时间（只进不退）
    public DateTime LogicalLicenseDate { get; set; } // 🎯 核心：逻辑授权时间（必须推进，不允许停留）
    public DateTime ActivationDate { get; set; } // 🔐 授权生效日期（来自授权码）
    public int ValidDays { get; set; }          // 🔐 有效天数（来自授权码）
    public string LicenseCodeHash { get; set; } = ""; // 🛡️ 授权码哈希
    public string MachineId { get; set; } = "";       // 🛡️ 机器ID绑定

    // 兼容旧字段（避免编译错误）
    public DateTime MaxSeenTime { get; set; } = DateTime.MinValue;
    public DateTime LicenseStartDate { get; set; } = DateTime.MinValue;
    public int ResetCount { get; set; } = 0;
    public DateTime LastResetTime { get; set; } = DateTime.MinValue;
    public int TotalUsedDays { get; set; } = 0;
}

/// <summary>
/// 时间验证结果
/// </summary>
public class UnifiedTimeValidationResult
{
    public bool IsValid { get; set; }
    public string Message { get; set; } = "";
}



/// <summary>
/// 时间重置结果
/// </summary>
public class TimeResetResult
{
    public bool WasReset { get; set; }
    public string Message { get; set; } = "";
}
